//
//  UIView+Extension.swift
//  GangHood
//
//  Created by FeiFu on 2021/5/17.
//

import UIKit

/*
 * Name: UIView+Extension
 * Description: UIView相关处理
 */
extension UIView {
    
    /// SwifterSwift: Border color of view; also inspectable from Storyboard.
    @IBInspectable public var borderColors: UIColor? {
        get {
            guard let color = layer.borderColor else { return nil }
            return UIColor(cgColor: color)
        }
        set {
            guard let color = newValue else {
                layer.borderColor = nil
                return
            }
            // Fix React-Native conflict issue
            guard String(describing: type(of: color)) != "__NSCFType" else { return }
            layer.borderColor = color.cgColor
        }
    }
    
    /// SwifterSwift: Border width of view; also inspectable from Storyboard.
    @IBInspectable public var borderW: CGFloat {
        get {
            return layer.borderWidth
        }
        set {
            layer.borderWidth = newValue
        }
    }
    
    /// SwifterSwift: Corner radius of view; also inspectable from Storyboard.
    @IBInspectable public var cornerR: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.masksToBounds = true
            layer.cornerRadius = abs(CGFloat(Int(newValue * 100)) / 100)
        }
    }
    
    // MARK: --  部分倒圆角
    func setRadius(_ radius: CGFloat, corners: UIRectCorner) {
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: CGFloat(radius), height: CGFloat(radius)))
        let maskLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.path = path.cgPath
        layer.mask = maskLayer
    }

//    // MARK: -- 倒成圆
//    func setHalfRadius() {
//        setRadius(radius: height / 2.0)
//    }

    // MARK: -  设置圆角
    /// 设置圆角
    /// - Parameters:
    ///   - radius: 圆角大小
    ///   - boderWidth: 边线宽
    ///   - boderColor: 边线颜色
    func setRadius(radius: CGFloat, boderWidth: Float = 0, boderColor: UIColor? = nil) {
        layer.cornerRadius = CGFloat(radius)
        layer.masksToBounds = true
        if boderColor != nil {
            layer.borderColor = boderColor?.cgColor
            layer.borderWidth = CGFloat(boderWidth)
        }
    }
    // MARK: -- 移除所有子视图
    func removeSubviews() {
        for subview in subviews {
            subview.removeFromSuperview()
        }
    }
}

// MARK: -- 相关手势操作
extension UIView {
    
    //MARK: - Tap closure保存
    private struct AssociatedKeys {
        static var tapClosure = "tapClosure"
    }
    private var tapClosure: () -> Void {
        get {
            if let closure = objc_getAssociatedObject(self, &AssociatedKeys.tapClosure) as? () -> Void {
                return closure
            } else {
                return {}
            }
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.tapClosure, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    // MARK: --  添加单手指单击手势
    ///
    /// - Parameter closure: 回调
    func addSingleTap(_ closure: @escaping () -> Void) {
        addTap(touches: 1, taps: 1, closure)
    }
    
    // MARK: --  重新添加单击手势（主要用于cell重用时避免多次添加手势）
    ///
    /// - Parameter closure: 回调
    func reAddSingleTap(_ closure: @escaping () -> Void) {
        removeTapGestures()
        addSingleTap(closure)
    }
    
    // MARK: -- 添加单手指双击手势
    ///
    /// - Parameter closure: 回调
    func addDoubleTap(_ closure: @escaping () -> Void) {
        addTap(touches: 1, taps: 2, closure)
    }
    
    // MARK: -- 添加点击手势
    /// - Parameters:
    ///   - touches: 几根手指
    ///   - taps: 点击次数
    ///   - closure: 回调
    func addTap(touches: Int, taps: Int, _ closure: @escaping () -> Void) {
        isUserInteractionEnabled = true
        tapClosure = closure
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleAction))
        tapGesture.numberOfTouchesRequired = touches
        tapGesture.numberOfTapsRequired = taps
        addGestureRecognizer(tapGesture)
    }
    
    // MARK: --  移除所有点击手势
    func removeTapGestures() {
        if self.gestureRecognizers != nil {
            for gesture in self.gestureRecognizers! {
                if gesture is UITapGestureRecognizer {
                    self.removeGestureRecognizer(gesture)
                }
            }
        }
    }
    
    // MARK: --  移除所有手势
    func removeAllGestures() {
        if self.gestureRecognizers != nil {
            for gesture in self.gestureRecognizers! {
                self.removeGestureRecognizer(gesture)
            }
        }
    }
    
    // MARK: --  私有触发点击回调
    ///
    /// - Parameter recognizer: 手势对象
    @objc private func handleAction(_ recognizer: UIGestureRecognizer) {
        if recognizer.state == .recognized {
            tapClosure()
        }
    }
}


// MARK: -- 渐变方向
enum UIGradientStyle: Int {
    /**
     *  Returns a gradual blend between colors originating at the leftmost point of an object's frame, and ending at the rightmost point of the object's frame.
     *  @since 1.0
     */
    case leftToRight
    /**
     *  Returns a gradual blend between colors originating at the topmost point of an object's frame, and ending at the bottommost point of the object's frame.
     *  @since 1.0
     */
    case topToBottom
    
    /**
     *  Returns a gradual blend between colors originating at the center of an object's frame, and ending at all edges of the object's frame. NOTE: Supports a Maximum of 2 Colors.
     *  @since 1.0
     *  暂未写完
     */
    case radial
    
}

// MARK: -- UIView颜色渐变
extension UIView {
    /// 添加渐变
    /// - Parameters:
    ///   - style: 方向，支持横向和竖向
    ///   - colors: 颜色值数组 2个
    ///   - frame: 大小
    ///   - radius: 倒圆大小
    @discardableResult func addGradient(style: UIGradientStyle, colors: [UIColor], radius: CGFloat = 0) -> CAGradientLayer{
        var startPoint = CGPoint(x: 0.0, y: 0.0)
        var endPoint = CGPoint(x: 0.5, y: 0.5)
        switch style {
            case .leftToRight:
                startPoint = CGPoint(x: 0.0, y: 0.5)
                endPoint = CGPoint(x: 1.0, y: 0.5)
            case .topToBottom:
                startPoint = CGPoint(x: 0.5, y: 0.0)
                endPoint = CGPoint(x: 0.5, y: 1.0)
            default :
                break
        }
        let points = (startPoint, endPoint)
        let gradientLayer =  addGradient(colors: colors,
                            point: points,
                            frame: bounds,
                            radius: radius)
        return gradientLayer
    }

    @discardableResult
    func addGradient(colors: [UIColor],
                     point: (CGPoint, CGPoint) = (CGPoint(x: 0.5, y: 0), CGPoint(x: 0.5, y: 1)),
                     locations: [NSNumber] = [0, 1],
                     frame: CGRect = CGRect.zero,
                     radius: CGFloat = 0,
                     at: UInt32 = 0) -> CAGradientLayer {
        let bgLayer1 = CAGradientLayer()
        bgLayer1.colors = colors.map { $0.cgColor }
        bgLayer1.locations = locations
        if frame == .zero {
            bgLayer1.frame = self.bounds
        } else {
            bgLayer1.frame = frame
        }
        bgLayer1.startPoint = point.0
        bgLayer1.endPoint = point.1
        bgLayer1.cornerRadius = radius
        self.layer.insertSublayer(bgLayer1, at: at)
        return bgLayer1
    }
    
    func addGradient(start: CGPoint = CGPoint(x: 0.5, y: 0),
                     end: CGPoint = CGPoint(x: 0.5, y: 1),
                     colors: [UIColor],
                     locations: [NSNumber] = [0, 1],
                     frame: CGRect = CGRect.zero,
                     radius: CGFloat = 0,
                     at: UInt32 = 0) {
        let bgLayer1 = CAGradientLayer()
        bgLayer1.colors = colors.map { $0.cgColor }
        bgLayer1.locations = locations
        bgLayer1.frame = frame
        bgLayer1.startPoint = start
        bgLayer1.endPoint = end
        bgLayer1.cornerRadius = radius
        self.layer.insertSublayer(bgLayer1, at: at)
    }
    // MARK: --
    func addGradient(start_color:String,end_color : String,frame : CGRect?=nil,cornerRadius : CGFloat?=0, at: UInt32 = 0){
        var bounds : CGRect = self.bounds
        if let frame = frame {
            bounds = frame
        }
        let bgLayer1 = CAGradientLayer()
        bgLayer1.colors = [UIColor.color(start_color).cgColor, UIColor.color(end_color).cgColor]
        bgLayer1.locations = [0, 1]
        bgLayer1.frame = bounds
        bgLayer1.startPoint = CGPoint(x: 0, y: 0.61)
        bgLayer1.endPoint = CGPoint(x: 0.61, y: 0.61)
        bgLayer1.cornerRadius = cornerRadius ?? 0
        self.layer.insertSublayer(bgLayer1, at: at)
    }
    // MARK: --
    func addGradient(start_color:String,
                     end_color : String,
                     frame : CGRect?=nil,
                     borader: CGFloat = 0,
                     boraderColor: UIColor = .clear,
                     at: UInt32 = 0,
                     corners: UIRectCorner?,
                     radius: CGFloat = 0) {
        var bounds : CGRect = self.bounds
        if let frame = frame {
            bounds = frame
        }
        let bgLayer1 = CAGradientLayer()
        bgLayer1.colors = [UIColor(named: start_color)!.cgColor, UIColor(named: end_color)!.cgColor]
        bgLayer1.locations = [0, 1]
        bgLayer1.frame = bounds
        bgLayer1.startPoint = CGPoint(x: 0, y: 0.61)
        bgLayer1.endPoint = CGPoint(x: 0.61, y: 0.61)
        bgLayer1.borderColor = boraderColor.cgColor
        bgLayer1.borderWidth = borader
        if corners != nil {
            let cornerPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners!, cornerRadii: CGSize(width: radius, height: radius))
            let radiusLayer = CAShapeLayer()
            radiusLayer.frame = bounds
            radiusLayer.path = cornerPath.cgPath
            bgLayer1.mask = radiusLayer
        }
        self.layer.insertSublayer(bgLayer1, at: at)
    }
    
    // MARK: -- 自定义渐变设置
    func addGradient(startPoint: CGPoint = CGPoint(x: 0, y: 0.5),
                     start_color:String,
                     endPoint: CGPoint = CGPoint(x: 1, y: 0.5),
                     end_color : String,
                     frame : CGRect? = nil,
                     cornerRadius : CGFloat?=0){
        var bounds : CGRect = self.bounds
        if let frame = frame {
            bounds = frame
        }
        let bgLayer1 = CAGradientLayer()
        bgLayer1.frame = bounds
        bgLayer1.startPoint = startPoint
        bgLayer1.endPoint = endPoint
        bgLayer1.colors = [UIColor.color(start_color).cgColor, UIColor.color(end_color).cgColor]
        bgLayer1.locations = [0, 1]
        bgLayer1.cornerRadius = cornerRadius ?? 0
        self.layer.addSublayer(bgLayer1)
    }
    
    // MARK: -- 添加垂直方向的渐变
    func addVerticalGradient(start_color:String,end_color : String,frame : CGRect?=nil,cornerRadius : CGFloat?=0){
        var bounds : CGRect = self.bounds
        if let frame = frame {
            bounds = frame
        }
        let bgLayer1 = CAGradientLayer()
        bgLayer1.colors = [UIColor.color(start_color).cgColor, UIColor.color( end_color).cgColor]
        bgLayer1.locations = [0, 1]
        bgLayer1.frame = bounds
        bgLayer1.startPoint = CGPoint(x: 0.5, y: 0)
        bgLayer1.endPoint = CGPoint(x: 1, y: 1)
        bgLayer1.cornerRadius = cornerRadius ?? 0
        self.layer.insertSublayer(bgLayer1, at: 0)
    }
    
    // MARK: -- 将当前视图转为UIImage
    func asImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }
}


// MARK: -- 红点处理

extension  UIView  {
    
    private struct RedAssociatedKeys {
         static var CMTRedViewKey: Void?
     }
     
    var red: UIView? {
        set {
            objc_setAssociatedObject(self, &RedAssociatedKeys.CMTRedViewKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        get {
            return objc_getAssociatedObject(self, &RedAssociatedKeys.CMTRedViewKey) as? UIView
        }
    }

    
    // MARK: -- 添加红点
    func showRedView(_ animation: Bool){
        if  animation {
            if red  ==  nil{
                //如果是空才加，免得重复加
                let v =  CMTRedView(frame: CGRect(x: bounds.width - 12, y: 6, width: 8, height: 8))
                red = v
                addSubview(v)
            }
            red?.isHidden = false
        }else {
            red?.isHidden = true
        }
    }
}

//红点视图
class CMTRedView: UIView {
    
    // MARK: -- 初始化
    override init(frame: CGRect) {
        super.init(frame: frame)
        layer.cornerRadius = frame.width/2.0
        layer.masksToBounds = true
        backgroundColor = UIColor.red
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
